package com.hiadechizi.dynamic.advise;

import com.hiadechizi.dynamic.annotation.RouterDataSource;
import com.hiadechizi.dynamic.holder.DataSourceHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import java.lang.reflect.Method;

/**
 * @author: wangdejun
 * @create: 2019-11-18 16:50
 **/
@Slf4j
@Aspect
@EnableAspectJAutoProxy
public class DynamicDataSourceAdvise {


    /**
     * 同时拦截类和方法上的注解是，无法将注解直接传递给方法的参数，必须手动获取
     */
    @Pointcut("@annotation(com.hiadechizi.dynamic.annotation.RouterDataSource)||@within(com.hiadechizi.dynamic.annotation.RouterDataSource)")
    public void pointcut() {

    }

    /**
     * 设置数据源
     *
     * @param joinPoint
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        RouterDataSource routerDataSource = method.getAnnotation(RouterDataSource.class);//获取方法上的注解
        if (routerDataSource == null) {
            routerDataSource = joinPoint.getTarget().getClass().getAnnotation(RouterDataSource.class);//获取类上面的注解
            if (routerDataSource == null) return;
        }
        log.debug("current datasource：{}", routerDataSource.value());
        DataSourceHolder.set(routerDataSource.value());
    }

    /**
     * 移除当前线程的数据源
     *
     * @param joinPoint
     */
    @After("pointcut()")
    public void after(JoinPoint joinPoint) {
        DataSourceHolder.remove();
    }
}
